package eventos.aceptar;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JOptionPane;

import logica.AtributoIdentificadorFaltanteException;
import logica.AtributoRepetidoException;
import logica.Entidad;
import logica.EntidadIdentificadoraFaltanteException;
import logica.EntidadRepetidaException;
import logica.IdExternoInexistenteException;
import logica.IdExternoRepetidoException;
import logica.IdentificadorVacioException;
import logica.SinNombreException;
import memento.IMemento;

import controlador.IObjDelModConRefExternaEntidad;

import vista.objetos.AtributoTipoNoSoportadoException;
import vista.objetos.EntidadGraficable;
import vista.objetos.ProyectoGraficable;
import vista.ventanas.VentanaEntidad;


public class EventoAceptarEntidadEditada  extends MouseAdapter {
	
	private VentanaEntidad ventana;
	private IObjDelModConRefExternaEntidad controlador;
	private EntidadGraficable entidad;
	private String nombreViejoEntidad;

	public EventoAceptarEntidadEditada(VentanaEntidad ventana, IObjDelModConRefExternaEntidad controlador, EntidadGraficable entidad)
	{
		super();
		this.ventana = ventana;
		this.controlador = controlador;
		this.entidad = entidad;
		this.nombreViejoEntidad = entidad.getObjetoDiagramaDecorado().getNombre();
	}
	
	public void mouseClicked(MouseEvent evento)
	{
		IMemento memento = this.controlador.getGraficableEditando();
		ProyectoGraficable proyecto = this.controlador.getProyectoActual();
		
		try 
		{
			if (this.ventana.getNombreEntidad().compareToIgnoreCase(this.nombreViejoEntidad) != 0) 
			{
				//=> cambio de nombre, hay q chequear q en el modelo no exista una entidad con ese nombre
				Entidad entidadTemp = new Entidad(this.ventana.getNombreEntidad());
				this.controlador.verificarSiSePuedeAgregarObjeto(entidadTemp);
			}
		
			/*
			 *  si la entidad cambió de nombre, pero siguió hasta acá es porque se puede agregar con el 
			 *  nuevo nombre.
			 *  si no cambió el nombre, simplemente cargo:
			 *  	- tipo de entidad
			 *  	- atributos
			 *  	- referencias externas
			 *  	- identificadores
			 */
			
			this.ventana.getEntidad();

			/*verifico que los nuevos atributos sean consistentes y las entidades a agregar tmb*/
			proyecto.verficarSiSePuedeEditar(entidad);
			
			this.entidad.borrarseDeLaHoja();
		
			/*altero todas las copias de esta entidad que puedan llegar a haber en los distintos diagramas*/
			proyecto.editar(entidad, this.ventana.getTipoDeEntidad().getTipoEntidadGraficable());

			
			this.controlador.actualizarGraficableConAtributos(this.entidad);
			//si hasta este punto no saltó ninguna excepción entonces guardo el estado anterior para deshacer
			this.controlador.guardarMemento(memento);
			this.controlador.sacarGraficableEditando();

			this.ventana.setVisible(false);
			this.ventana = null;
		}
		catch (SinNombreException e)
		{
			JOptionPane.showMessageDialog(this.ventana, "La entidad debe tener nombre.", "Entidad sin nombre", JOptionPane.ERROR_MESSAGE);
			memento.cargarMemento();
		} 
		catch (EntidadRepetidaException e)
		{
			JOptionPane.showMessageDialog(this.ventana, "Ya existe en el modelo una entidad con este nombre: " + ventana.getNombreEntidad(), "Entidad repetida", JOptionPane.ERROR_MESSAGE);
			memento.cargarMemento();
		} 
		catch (AtributoRepetidoException e) 
		{
			JOptionPane.showMessageDialog(this.ventana, e.getMessage(), "Atributo repetido", JOptionPane.ERROR_MESSAGE);
			memento.cargarMemento();
		} 
		catch (IdExternoRepetidoException e) 
		{
			JOptionPane.showMessageDialog(this.ventana, e.getMessage(), "Referencia externa repetida", JOptionPane.ERROR_MESSAGE);
			memento.cargarMemento();
		}
		catch (AtributoIdentificadorFaltanteException e) 
		{
			JOptionPane.showMessageDialog(this.ventana, e.getMessage(), "Error en el identificador", JOptionPane.ERROR_MESSAGE);
			memento.cargarMemento();
		}
		catch (EntidadIdentificadoraFaltanteException e) 
		{
			JOptionPane.showMessageDialog(this.ventana, e.getMessage(), "Error en el identificador", JOptionPane.ERROR_MESSAGE);
			memento.cargarMemento();
		}
		catch (IdentificadorVacioException e) 
		{
			JOptionPane.showMessageDialog(this.ventana, e.getMessage(), "Error en el identificador", JOptionPane.ERROR_MESSAGE);
			memento.cargarMemento();
		}
		catch (IdExternoInexistenteException e) 
		{
			JOptionPane.showMessageDialog(this.ventana, e.getMessage(), "Error en referencia externa", JOptionPane.ERROR_MESSAGE);
			// la vuelvo a agregar porque la excepción si salta salta después de borrar la entidad de la hoja de dibujo
			this.controlador.actualizarGraficableConAtributos(this.entidad);
			memento.cargarMemento();
		} 
		catch (AtributoTipoNoSoportadoException e) 
		{// Se supone q no debería pasar
			JOptionPane.showMessageDialog(this.ventana, e.getMessage(), "Error en el tipo de atributo", JOptionPane.ERROR_MESSAGE);
			memento.cargarMemento();
		}
		catch (Exception e) 
		{// se supone q no debería producirse 
			JOptionPane.showMessageDialog(this.ventana, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
			memento.cargarMemento();
		}
	}
}